# _*_ coding: utf-8 _*_
"""
author: lianGang
email: 1542652663@qq.com
"""

"""
实现自定义容器
"""
import bisect
import collections


class SortedItems(collections.Sequence):
    def __init__(self, initial=None):
        self._items = sorted(initial) if initial is not None else []

    # required sequence methods
    def __getitem__(self, index):
        return self._items[index]

    def __len__(self):
        return len(self._items)

    # methods for adding an item in the right location
    def add(self, item):
        bisect.insort(self._items, item)


# items = SortedItems([5,1,3])
# print(list(items))
# print(items[0], items[-1])
# items.add(2)
# print(list(items))

# 属性的代理访问
class A_obj:
    def spam(self, x):
        print('A.spam', x)

    def foo(self):
        print('A.foo')

    def __foo2(self):
        print('A.foo2')

class B:
    def __init__(self):
        self._a = A_obj()

    def spam(self,x):
        print('B.spam', x)

    def bar2(self):
        print('B.bar2')

    def __getattr__(self, name):
        return getattr(self._a, name)

# b1 = B()
# b1.spam(1)
# b1.bar2()


# 在类中定义多个构造器
# 实现一个类，多种方式初始化
import time

class Date:
    """"方法一 使用类方法"""
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    # alternate constructor
    @classmethod
    def today(cls):
        t = time.localtime()
        return cls(t.tm_year, t.tm_mon, t.tm_mday)


# a = Date(2012, 12,21)
# b = Date.today()

# 创建不调用init方法的实例
class Date2:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

# d1 = Date2.__new__(Date2)
# data = {'year':2012, 'month':8, 'day':29}
# for key, value in data.items():
#     setattr(d1, key, value)

# 利用Mixins扩展类功能


# # 通过字符串调用对象方法
# # 方法1
# import math
#
# class Point:
#     def __init__(self, x, y):
#         self.x = x
#         self.y = y
#
#     def __repr__(self):
#         return  'Point({!r:}, {!r:})'.format(self.x, self.y)
#
#     def distance(self, x, y):
#         return math.hypot(self.x-x, self.y-y)
#
#
# p = Point(2,3)
# d = getattr(p, 'distance')(0, 0)
# # 方法二
# import operator
#
# print(operator.methodcaller('distance', 0, 0)(p))


# 8.21 实现访问者模式


# 循环引用数据结构的内存管理
# weakref 弱引用
import weakref

class Node:
    def __init__(self, value):
        self.value = value
        self._parent = None
        self.children = []

    def __repr__(self):
        return 'Node({!r:})'.format(self.value)

    @property
    def parent(self):
        return None if self._parent is None else self._parent()

    @parent.setter
    def parent(self, node):
        self._parent = weakref.ref(node)
        print(self.value, 'self._parent')

    def add_child(self, child):
        self.children.append(child)
        child.parent = self



root = Node('parent')
c1 = Node('child')
root.add_child(c1)
print(c1.parent)
